package study.JavaAdvanced;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * date:2025.10.17
 * title:多线程
 * author:fzy
 */

/*
进程---正在运行的程序，系统进行资源分配和调用的独立单位
线程---进程中的单个顺序控制流，是一条执行路径
单线程 -- 一个进程如果只有一条执行路径
多线程 -- 一个进程又多条执行路径
 */
public class Java_9 {
    public static void main(String[] arg) {
////        ThreadManager.ThreadTest();
//
//        try{
//            ThreadManager.myThreadManager();
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//        ThreadManager.RunnableTest();
        TicketManager.StartSale();

    }
}

class ThreadManager {
    static void ThreadTest() {
        MyThread MyThread_one = new MyThread();
        MyThread myThread_two = new MyThread();
        MyThread_one.setName("thread_one");
        myThread_two.setName("thread_two");
        myThread_two.setMyPriority(10);
        MyThread_one.setMyPriority(1);
        System.out.println(myThread_two.getName() + "优先级" + myThread_two.getMyPriority());
        System.out.println(MyThread_one.getName() + "优先级" + MyThread_one.getMyPriority());
        MyThread_one.start();
        myThread_two.start();
    }

    /*
   线程控制：
   static void sleep(long mills) 让当前的线程停留指定的毫秒数
   void join() 等待这个线程死亡
   void setDaemon(boolean on) 将此线程编辑为守护线程，当运行程序都是守护线程，java虚拟机退出,主线程执行之后，其他线程必须消失
   */
    static void myThreadManager() throws InterruptedException {
//        MyThread Cc  = new MyThread();
//        MyThread Lb = new MyThread();
//        MyThread Sq  = new MyThread();
//        Cc.setName("曹操");
//        Lb.setName("刘备");
//        Sq.setName("孙权");
        //获取主线程
        //Thread.currentThread() 获取主线程
        Thread.currentThread().setName("刘备");
        MyThread gy = new MyThread("关羽");
        MyThread zf = new MyThread("张飞");
        gy.setDaemon(true);
        gy.start();
        zf.start();
        for (int i = 0; i < 10; i++) {
            Thread.sleep(1000);
            System.out.println(Thread.currentThread().getName() + "---" + i);
        }

//        Cc.start();
//        Cc.join();
//        Lb.start();
//        List<Thread> threadList = new ArrayList<>();
//        threadList.add(Cc);
//        threadList.add(Lb);
//        threadList.add(Sq);
//        for(Thread c : threadList){
//            c.start();
//        }
    }

    /*
    相比继承Thread类，实现Runnable接口的好处
    可以多继承
    可以实现统一资源多执行
     */
    static void RunnableTest() {
        MyRunnable myRunnable = new MyRunnable();
        Thread t1 = new Thread(myRunnable);
        Thread t2 = new Thread(myRunnable);
        t1.setName("t1");
        t2.setName("t2");
        t1.start();
        t2.start();

    }

}

/*
实现方式 -- 1
1.继承thread类
2.重写thread的run()方法:MyThread并不是所有的代码都需要被线程执行，所以需要重写run(0方法
 */

class MyThread extends Thread {
    //封装需要多线程的逻辑
    //run方法并没有启动此线程
    //get/set name() 编辑名称，
    int num = 30;

    MyThread(String name) {
        //带参构造方法，设置线程name
        super(name);
    }

    MyThread(String name, int num) {
        super(name);
        this.num = num;
    }

    MyThread() {

    }

    @Override
    public void run() {
        for (int i = 0; i < num; i++) {
            try {
                //线程等待1s
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(getName() + "__ " + i);
        }
    }

    /*
    线程调度
        分时调度模型：所有线程轮流使用cpu
        抢占式模型：优先让优先级高的线程使用cpu，优先级相同就会随机选择一个，优先级高德获取时间多
        public final int getPriority():返回线程优先级
        public final void setPriority(int newPriority):设置优先级 1 - 10
     */
    public void setMyPriority(int priority) {
        super.setPriority(priority);
    }

    public int getMyPriority() {
        return super.getPriority();
    }
    /*
    线程生命周期
    新建 -- > start() -- > 就绪(等待cpu调度) -- > (run 结束或者stop(0))死亡
                                  就绪<--  没有cpu的执行权(阻塞) < --  其他线程抢走了Cpu
     */
}

/*
实现方式2
实现runnable接口 将自定义对象作为参数传递
1.定义一个类实现runnable接口
2.重写run方法
3.创建MyrRunnable对象
4.创建Thead对象
5.启动线程
 */

class MyRunnable implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(Thread.currentThread().getName() + "---" + i);
        }
    }
}


class TicketManager {
    static void StartSale() {
        TicketSales ticketSales = new TicketSales();
        Thread A = new Thread(ticketSales);
        Thread B = new Thread(ticketSales);
        A.start();
        B.start();

    }
}

/*
线程同步
1.是否是多线程
2.是否有共享数据
3.是否有多条语句操作共享数据



/*
案例1：买票小子
 */
class TicketSales implements Runnable {
    private int ticketNum = 100;
    private int i = 0;

    /*
lock锁
//void lock()获得锁
//void unlock()释放锁
 */

    private Lock lock = new ReentrantLock();
    /*
    同步代码块
Synchronized(任意对象){
    多条语句操作共享数据的代码
}
     */
//    @Override
//    public void run() {
//
//        while (ticketNum > 0) {
//            if(i%2 == 0){
//                synchronized (this){
//                    try {
//                        Thread.sleep(100);
//                    } catch (InterruptedException e) {
//                        throw new RuntimeException(e);
//                    }
//                    System.out.println(Thread.currentThread().getName() + "剩余" + this.ticketNum);
//                    this.ticketNum--;
//                }
//            }else {
//                sellTicket();
//            }
//            i++;
//        }
//    }

    @Override
    public void run() {
        try{
            lock.lock();
            while (ticketNum > 0) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println(Thread.currentThread().getName() + "剩余" + this.ticketNum);
                this.ticketNum--;

            }
        } catch (RuntimeException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }

    }


    /*
    同步方法
     */
//    private void sellTicket(){
//        synchronized (this){
//            try {
//                Thread.sleep(100);
//            } catch (InterruptedException e) {
//                throw new RuntimeException(e);
//            }
//            System.out.println(Thread.currentThread().getName() + "剩余" + this.ticketNum);
//            this.ticketNum--;
//        }
//    }

    /*
     静态方法的同步锁是其静态类
     */
    private synchronized void sellTicket(){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(Thread.currentThread().getName() + "剩余" + this.ticketNum);
            this.ticketNum--;
    }
    /*
    线程安全的类
    stringBuffer
    vector
    Hashtable
     */
}




